import numpy as np
import os
import cv2
from pathlib import Path
os.chdir(os.path.dirname(__file__))
from typing import List, Dict
import csv
import tkinter as tk
from tkinter import filedialog

# ---------  整幅图读取 ---------
def get_raw_u16(path, width, height):
    print(path)
    """以 uint16 读取单通道 raw 文件，shape -> (H,W,1)"""
    img = np.fromfile(path, dtype=np.uint16)
    if img.size != width * height:
        raise ValueError('文件字节数与 width×height 不符')
    return img.reshape(height, width)

def list_all_files_with_dir(root_folder):
    result = []
    for dirpath, dirnames, filenames in os.walk(root_folder):
        for filename in filenames:
            full_path = os.path.join(dirpath, filename)
            result.append({
                'file_path': full_path,
                'directory': dirpath
            })
    return result

# ---------  交互式 ROI 选取 ---------
def select_roi_once(img16,  max_short_edge=720):

    # 3. 等比缩放
    h, w = img16.shape[:2]
    scale = max_short_edge / min(h, w)
    new_w, new_h = int(w * scale), int(h * scale)
    img_small = cv2.resize(img16, (new_w, new_h), interpolation=cv2.INTER_AREA)

    # 4. 选框
    roi_small = cv2.selectROI('select ROI (scaled)', img_small, showCrosshair=True, fromCenter=False)
    cv2.destroyWindow('select ROI (scaled)')
    if roi_small == (0, 0, 0, 0):
        raise RuntimeError('未选择有效 ROI，程序终止。')

    # 5. 坐标还原
    x, y, w, h = [int(v / scale) for v in roi_small]
    return x, y, w, h

# ---------  ROI 选取 ---------
def get_raw_u16_roi(path, width, height, x, y, w, h):
    """
    直接从 raw 文件里抠 ROI，避免整幅图进内存。
    返回 shape -> (h, w, 1)
    """
    # 计算偏移：row_start、row_end
    row_start, row_end = y, y + h
    col_start, col_end = x, x + w

    # 每行字节数
    bytes_per_row = width * 2          # uint16 = 2 B
    roi_rows = row_end - row_start
    roi_cols = col_end - col_start

    roi = np.empty((roi_rows, roi_cols), dtype=np.uint16)

    with open(path, 'rb') as f:
        for i in range(roi_rows):
            # 跳到指定行开头
            f.seek((row_start + i) * bytes_per_row + col_start * 2)  # 修正：bytes_per_row
            # 读取当前行的ROI部分
            data = f.read(roi_cols * 2)
            if len(data) < roi_cols * 2:
                raise ValueError(f"文件读取不完整，期望 {roi_cols * 2} 字节，只读取到 {len(data)} 字节")
            roi[i, :] = np.frombuffer(data, dtype=np.uint16)

    return roi.reshape(h, w)

if __name__ == '__main__':

    files  = filedialog.askdirectory(title="请选择文件夹")
    info_list = list_all_files_with_dir(files)
    full_img = get_raw_u16(info_list[0]['file_path'], 3072, 3072)
    x, y, w, h = select_roi_once(full_img,720)
    print('ROI 坐标:', x, y, w, h)
    with open('result.csv', 'a', encoding='utf-8', newline='') as f:
        writer = csv.writer(f, delimiter=',')
        for item in info_list:
            image = get_raw_u16_roi(item['file_path'], 3072, 3072, x, y, w, h)
            mean_1d = np.round(np.mean(image, axis=0)).astype(np.uint16)
            mean=np.mean(mean_1d)
            std = np.std(mean_1d)
            writer.writerow([item['directory'], std,mean])
